<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
<script>
// 模拟 bind
Function.prototype.bind1 = function () {
    // 将参数拆解为数组
    const args = Array.prototype.slice.call(arguments);

    // 获取 this（数组第一项）
    const t = args.shift(); // shift 返回第一个元素, 并修改原数组

    // fn1.bind(...) 中的 fn1
    const self = this;

    // 返回一个函数
    return function () {
        return self.apply(t, args);
    }
}

Function.prototype.bind2 = function(...args) {
    const params = Array.from(args);
    const _this = params[0];

    return () => {
        this.apply(_this, params.slice(1));
    }
}

function fn1(a, b, c) {
    console.log('this', this)
    console.log(a, b, c)
    return 'this is fn1'
}

const fn2 = fn1.bind1({x: 100}, 10, 20, 30)
const res = fn2()
console.log(res)


// TODO: 总结
// [].slice === Array.prototype.slice
// [].slice 是实例[]去调用slice, this 指向[], [].length === 0
// 而 Array.prototype.slice 中, this 指向 Array.prototype, Array.prototype.length === 0
// 因此直接调用是没有意义的, 要配合call apply
</script>
</body>
</html>